package com.feib.ebilling.job;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.enterprisedt.net.ftp.FTPFile;
import com.enterprisedt.net.ftp.FileTransferClient;
import com.feib.ebilling.job.dao.BankingFeedbackDao;
import com.feib.ebilling.job.service.FtpService;
import com.feib.ebilling.job.util.StringUtils;

/**
 * @title (#)WrittenOffFeedback.java<br>
 * @description 中租車貸策略聯盟銷帳資料回饋檔TYPAY<br>
 * @author Fiona Huang<br>
 * @version 1.0.0 2011/11/09
 * @copyright Far Eastern International Bank Copyright (c) 2011<br>
 * @2011/11/09 create by Fiona Huang<br>
 * @remark 一定要在BankingFeedbackBussinessDate.bat之後執行，限中租使用<br>
 */


@Service("writtenOffFeedback")
public class WrittenOffFeedback {
	public static Logger logger = LoggerFactory.getLogger(WrittenOffFeedback.class);

	/* 中租車貸策略聯絡的代號  */
	private static String chailease = "865170966930";
	
	public static final SimpleDateFormat BASIC_DATE_TIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

	@Resource(name = "ftpService")
	private FtpService ftpService;

	@Resource(name="ftpProperties")
    private Properties ftpProperties;
	
	public static Map<String, String> CHANEL_CODE = new HashMap<String, String>();
    static
    {
        CHANEL_CODE.put("7111111", "1");        
        CHANEL_CODE.put("TFM", "2"); 
        CHANEL_CODE.put("HILIFE", "3");
        CHANEL_CODE.put("OKCVS", "4");
        CHANEL_CODE.put("POST", "5");
    }
    
    @Resource(name="bankingFeedbackDao")
    private BankingFeedbackDao bankingFeedbackDao;
    
	public static void main(String[] args) {
		
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				new String[] { "applicationContext-config.xml",	"applicationContext-dao.xml",
							   "applicationContext-properties.xml" });

		Date start = new Date();
		
		if (null == args || 0 == args.length) {
			System.out.println("WrittenOffFeedback [865170966930]");
			return;
		}else if (1 == args.length){	
			/* 處理系統日當日所有中租回饋檔案 */
			chailease = args[0];
		}
		
		logger.info("[開始] 中租車貸策略聯盟銷帳資料回饋檔  - {}",	BASIC_DATE_TIME_FORMAT.format(start));
		try {
			WrittenOffFeedback writtenOffFeedback = (WrittenOffFeedback) ctx.getBean("writtenOffFeedback");
			writtenOffFeedback.getFiles("FEIB", "TYPAY");
		} catch (Exception e) {
			logger.error("[錯誤]" + e.getMessage(), e);
		} finally {
			Date end = new Date();
			logger.info("[結束] 中租車貸策略聯盟銷帳資料回饋檔 - {}", BASIC_DATE_TIME_FORMAT.format(start));
			logger.info("共費時 - " + ((end.getTime() - start.getTime()) / 1000) + " 秒");
		}
	}
	
	public void getFiles(String sChanel,String FileName)
    {
        FileTransferClient ftp = null;
        /* 取得FTP設定 */
        String host  = ftpProperties.getProperty(sChanel + "#FTPServerIP");
        String username = ftpProperties.getProperty(sChanel + "#FTPUserName");
        String password = ftpProperties.getProperty(sChanel + "#FTPPassword");
        String localFolder = ftpProperties.getProperty(sChanel + "#LocalFolder");
        String remoteFolder = ftpProperties.getProperty(sChanel + "#RemoteFolder");
        
        logger.info("FTP Server Connect : {}", host);
        logger.info("FTP User Name : {}", username);
        logger.info("FTP Local Directory : {}", localFolder);
        logger.info("FTP Remote Directory : {}", remoteFolder);
        
        
        try {
            ftp = new FileTransferClient();
            ftp.setRemoteHost(host);
            ftp.setUserName(username);
            ftp.setPassword(password); 
            ftp.connect();
            if (ftp.isConnected()){

                /* 切換FTP目錄  */
                if (remoteFolder != null && !remoteFolder.trim().equals("")){
                    ftp.changeDirectory(remoteFolder);
                    logger.info("Directory change to {}", ftp.getRemoteDirectory());
                }
                
                /* 列出Server上的檔案   */
                FTPFile[] ftpFiles = ftp.directoryList();
                String sFileName = null;
                for(FTPFile ftpFile: ftpFiles)
                {
                    if (ftpFile.isDir()) {
                        logger.info("{} is directory. skip" , ftpFile.getName());
                        continue;
                    }else if (ftpFile.isLink()) {
                        logger.info("{} is Link. skip" , ftpFile.getName());
                        continue;
                    }else{
                    	/* 讀取檔案 */
                        sFileName = ftpFile.getName().toUpperCase();
                        /* 過濾檔名前五位是 TYPAY */
                        if (!FileName.equals(sFileName.substring(0, 5))) continue;
                        /* 副檔名是.TXT */
                        if (!sFileName.substring(sFileName.length() - 4,sFileName.length()).equals(".TXT")) continue;
                        /* 下載檔案 */ 
                        logger.info("File {} size is {} Bytes", sFileName, ftp.getSize(sFileName));
                        ftp.downloadFile(localFolder, sFileName);  
                        logger.info("{} is download", sFileName);
                        /* 開啟檔案 */
                        File uploadedFile = new File(localFolder + "\\" + sFileName);
                        StringBuffer sbf = new StringBuffer();
                        long total = 0;           
                        
                        if(uploadedFile.exists()){
    					    String str = null;
    					    String channel ="";
    					    String userno ="";    					   
    					    FileInputStream fileInputStream = new FileInputStream(uploadedFile);
    			            BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream, "Big5"));    			          			            
    			            while ((str = reader.readLine()) !=null ){ 
    			                if(str.length() > 0){
    			                    //處理讀取BOM(byte-order mark)格式檔案,在讀取utf8檔案的開頭會有utf8檔案格式的標記,需略過此標記再重串內容,標記16進位EF BB BF 
    			                    int c = str.charAt(0);
    			                    if(c == 65279){
    			                    	str = str.substring(1, str.length());
    			                    }
    			                }
    			                /* 檔案有中文需特殊處理 */    			               
    			                sbf.append(str.substring(0, str.length() - 17));
        						if (StringUtils.DBCSsubstring(str, 222, 223).equals("0")){
        							/* 優利預設帶0，由eBilling判斷是否為超商、郵局通路代碼 */
            						userno = StringUtils.DBCSsubstring(str, 223, 239);            						
            						channel = getChannel(userno);
	        						if(channel.equals("")){
	        						   /* 銀行通路 */
	        						   sbf.append("0");
	        						   channel = "0";
	        						}else{
	       							   /* 超商、郵局通路 */
	        						   sbf.append(channel);
	        						   
	        						   /* 中租補資料用 */
	        						   StringBuffer sbfTemp = new StringBuffer();	
	        						   /* 扣款日 */
	        						   sbfTemp.append(StringUtils.DBCSsubstring(str,197,205) + "\t");
	        						   /* 繳費帳號  */
	        						   sbfTemp.append(StringUtils.DBCSsubstring(str,223,239) + "\t");
	        						   /* 客戶編號 */
	        						   sbfTemp.append(StringUtils.DBCSsubstring(str,103,119) + "\t");
	        						   /* 客戶名稱 */
	        						   sbfTemp.append(StringUtils.DBCSsubstring(str,35,103) + "\t");
	        						   /* 繳費金額 */
	        						   int iTemp = Integer.parseInt(StringUtils.DBCSsubstring(str, 135, 143))+
	        								       Integer.parseInt(StringUtils.DBCSsubstring(str, 143, 151));		   
	        						   sbfTemp.append(String.valueOf(iTemp) + "\t");
	        						   /* 繳款通路 */	        						   
	        						   if (channel.equals("1")){
	        							   sbfTemp.append("統一超商\t");
	        						   }else if (channel.equals("2")){
	        							   sbfTemp.append("全家超商\t");
	        						   }else if (channel.equals("3")){
	        							   sbfTemp.append("萊爾富超商\t");
	        						   }else if (channel.equals("4")){
	        							   sbfTemp.append("ＯＫ超商\t");
	        						   }else if (channel.equals("5")){
	        							   sbfTemp.append("郵局超商\t");	   
	        						   }
	        						   //logger.info("{}",sbfTemp.toString());
	        						}
        						}else{
        							/* 優利有回饋通路代碼 */
        							sbf.append(StringUtils.DBCSsubstring(str, 222, 223));
        						}
        						sbf.append("\r\n");
        						logger.info("虛擬帳號:{}, 繳款管道:{}", userno, channel);
        					}
        					total++;
                        }
                        logger.info("中租車貸策略聯盟銷帳資料筆數:{}", total);
                        /* 轉上傳至中租FTP Sever */
                        ftpService.putFTPFile(chailease, "", sbf.toString(), sFileName);
            			/* 處理過的檔案修改檔名 */
            			logger.info("{} is upload", sFileName);
                        ftp.rename(sFileName, sFileName.substring(0, sFileName.length() - 4) + ".bak");
                        /* 異動檔案名稱 */
                        logger.info("{} is rename", sFileName.substring(0, sFileName.length() - 4) + ".bak");
                    }   
                }
            }
        }
        catch (Exception ex) {
        	logger.error("[錯誤]" + ex.toString(), ex);
        }
        finally
        {
            if (null != ftp)
                try {
                    ftp.disconnect(true);
                }
                catch (Exception ex) {
                	logger.error("[錯誤]" + ex.toString(), ex);
                }
        }
    }
	
	
	
    @Transactional(readOnly = false)
    public String getChannel(String userno) {
        // 取得 DB Connection 
        Connection con = DataSourceUtils.getConnection(bankingFeedbackDao.getDataSource());
        Statement stmt = null;
        String channel ="";
        try {
            stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            String sql = "select * from FEEDBACK_LOG where USERNO = '" + userno + "' ";
            ResultSet rs = null;
            try {
                rs = stmt.executeQuery(sql);
                if (rs.next()){
                	channel = CHANEL_CODE.get(rs.getString("CHANNEL"));
                }else{
                	channel = "";
                }
            }
            finally {
                JdbcUtils.closeResultSet(rs);
            }
            return channel;
        }
        catch (Exception e) {
            JdbcUtils.closeStatement(stmt);
            stmt = null;
            DataSourceUtils.releaseConnection(con, bankingFeedbackDao.getDataSource());
            con = null;
            throw new RuntimeException(e);
        }
        finally
        {
            JdbcUtils.closeStatement(stmt);
            stmt = null;
            DataSourceUtils.releaseConnection(con, bankingFeedbackDao.getDataSource());
            con = null;
        }
    }
}
